package com.nit.lab.service.system.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.code.kaptcha.Producer;
import com.nit.lab.dto.basic.UserDTO;
import com.nit.lab.dto.system.*;
import com.nit.lab.dto.utils.OpResultDTO;
import com.nit.lab.service.basic.UserService;
import com.nit.lab.service.system.AccountService;
import com.nit.lab.service.system.RoleService;
import com.nit.lab.utils.JWTUtil;
import com.nit.lab.utils.RedisUtil;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Encoder;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.List;

@Service
public class AccountServiceImpl implements AccountService {

    @Value(value = "${application.jwt.expire}")
    private Integer expire;
    @Resource
    private Producer kaptchaProducer;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private UserService userService;
    @Resource
    private RoleService roleService;

    @Override
    public JSONObject loginCheck(String loginName, String loginPwd) throws Exception {
        JSONObject jsonObject = new JSONObject();
        TokenDTO tokenDTO = new TokenDTO();
        OpResultDTO opResult = new OpResultDTO();
        AccountDTO accountDTO = new AccountDTO();
        UserDTO userDto = userService.loginCheck(loginName);
        if (userDto != null && userDto.getUserType().equals(0L)) {
            opResult.setResult(JSONObject.parseObject("{ isLogin: false }"));
            jsonObject.put("data", opResult);
            jsonObject.put("message", "此用户已停用");
            jsonObject.put("status", 401);
        } else if (userDto == null || !userDto.getLoginPwd().equals(loginPwd)) {
            opResult.setResult(JSONObject.parseObject("{ isLogin: false }"));
            jsonObject.put("data", opResult);
            jsonObject.put("message", "用户名或密码错误");
            jsonObject.put("status", 401);
        } else {
            accountDTO.setId(userDto.getUserId());
            accountDTO.setName(userDto.getUserName());
            accountDTO.setRoleId(String.valueOf(userDto.getRoleId()));
            // 生成签名DTO，包含账号(用户)ID
            tokenDTO.setAccountId(userDto.getUserId());
            tokenDTO.setUnitId(userDto.getUnitId());
            tokenDTO.setUnitFather(userDto.getUnitFather());
            tokenDTO.setUnitType(userDto.getUnitType());
            accountDTO.setToken(JWTUtil.createSign(tokenDTO.toString(), expire));
            opResult.setResult(accountDTO);
            jsonObject.put("data", opResult);
            jsonObject.put("message", "");
            jsonObject.put("status", 200);
        }
        return jsonObject;
    }

    @Override
    public AccountDTO getInfo(String token) throws Exception {
        AccountDTO accountDTO = new AccountDTO();
        Long roleId = 0L;
        TokenDTO tokenDTO = JWTUtil.verifyToken(token);
        UserDTO userDto = userService.getByUserId(tokenDTO.getAccountId());
        roleId = userDto.getRoleId();
        accountDTO.setId(userDto.getUserId());
        accountDTO.setName(userDto.getUserName());
        accountDTO.setUsername(userDto.getLoginName());
        accountDTO.setAvatar(userDto.getUserImage());
        accountDTO.setCreateTime(userDto.getGmtCreate());
        accountDTO.setRoleId(String.valueOf(userDto.getRoleId()));
        accountDTO.setToken(JWTUtil.createSign(tokenDTO.toString(), expire));
        List<PermissionDTO> listPermissionDto = roleService.listPermissionByRoleId(roleId);
        RoleDTO roleDTO = roleService.getRoleByRoleId(roleId);
        roleDTO.setPermissions(listPermissionDto);
        accountDTO.setRole(roleDTO);
        return accountDTO;
    }

    @Override
    public KaptchaDTO getKaptcha() throws Exception {
        // 生成验证码
        String text = kaptchaProducer.createText();
        BufferedImage bufferedImage = kaptchaProducer.createImage(text);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(bufferedImage, "png", outputStream);
        BASE64Encoder base64Encoder = new BASE64Encoder();
        String base64 = base64Encoder.encode(outputStream.toByteArray());
        String captchaBase64 = "data:image/png;base64," + base64.replaceAll("\r\n", "");
        // 存入Redis数据库
        String randomId = RandomStringUtils.random(15, true, true);
        redisUtil.set(randomId, text, 60);
        // 生成验证码返回数据
        KaptchaDTO kaptchaDTO = new KaptchaDTO();
        kaptchaDTO.setUuid(randomId);
        kaptchaDTO.setImage(captchaBase64);
        kaptchaDTO.setExpire(60);
        return kaptchaDTO;
    }
}
